#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <stdarg.h>
#include "shell.h"
#include "arr.h"

#define LEN 1000 //设置测试数组的大小
#define ROUND 100 //设置测试的轮数
#define LOG_LEVEL 0 //1-打印 0-不打印


void (*funcArr[])(int*,int)={straightInsertSort,bubbleSort,
	shellSort,quickSort};
char *msgArr[]={"直接插入排序","冒泡排序","Shell排序","快速排序"};
int sortLen=sizeof(funcArr)/sizeof(void *);//排序的种类

static void myPrintf(char *fmt,...){
	if(LOG_LEVEL == 1){
		va_list args;
		va_start(args, fmt);
		vprintf(fmt, args);
		va_end(args);
	}
}

int main(int argc, const char *argv[])
{
	srand((unsigned)time(NULL));
	//记录每轮各算法的成绩
	//行(ROUND)：轮；列(SORT_TYPE)：各种算法的本轮的成绩
	int** record=(int**)malloc(sizeof(int*)*ROUND);
	for(int i=0;i<ROUND;i++){
		record[i]=(int*)malloc(sizeof(int)*sortLen);
	}

	for(int i=0;i<ROUND;i++){
		//随机生成一个数组
		int *arr=createArr(LEN);

		//打印数据的内容
		//TODO myPrintf(">>待排序数列生成完成:\n");
		//TODO printArr(arr, LEN);
		//TODO printf("\n");

		for(int j=0;j<sortLen;j++){
			int *arr1=copyArr(arr, LEN);
			clock_t t0=clock();
			funcArr[j](arr1, LEN);//调用排序算法
			clock_t t1=clock();

			record[i][j]=t1-t0;

			//TODO myPrintf(">>[%s]完成，耗时[%ld]个系统Clock\n", msgArr[j], 
			//		t1-t0);
			//TODO printArr(arr1, LEN);
			freeArr(arr1);
			arr1=NULL;
			//TODO printf("\n");
		}

		//回收内存
		freeArr(arr);
		//TODO myPrintf("*************************\n");
	}

	//打印成绩
	//printf("ROUND\t算法名称\t排序效率\n");
	for(int i=0;i<ROUND;i++){
		printf("ROUND\t算法名称\t排序效率\n");
		for(int j=0;j<sortLen;j++){
			printf("%-2d\t%s\t%d\n",i,msgArr[j],record[i][j]);
		}
		printf("-----------------------------------------------\n");
	}

	//统计结果
	printf("序号\t算法名称\t最大值\t最小值\t平均值\n");
	for(int j=0;j<sortLen;j++){//依次遍历每种算法
		int max,min,sum;
		max=min=sum=record[0][j];
		for(int i=1;i<ROUND;i++){
			if(record[i][j]>max)
				max=record[i][j];
			if(record[i][j]<min)
				min=record[i][j];
			sum+=record[i][j];
		}
		printf("%-3d\t%s\t%-3d\t%-3d\t%-.2lf\n", j+1, msgArr[j],max,min,
				(float)(sum)/ROUND);
	}
	

	//回收
	for(int i=0;i<ROUND;i++){
		free(record[i]);
	}
	free(record);
	
	return 0;
}
